﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.Threading.Tasks;
using System.Text.RegularExpressions;


public static class Helper
{
    public static T ToJson<T>(this string str)
    {
        var obj = JsonConvert.DeserializeObject<T>(str);

        return obj;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="indented">是否进行格式缩进</param>
    /// <returns></returns>
    public static string ToJsonString(this object obj, bool indented = false)
    {
        if (obj == null)
        {
            return "{}";
        }

        if (indented)
        {
            var jsonStr = JsonConvert.SerializeObject(obj, Formatting.Indented);
            return jsonStr;
        }
        else
        {
            var jsonStr = JsonConvert.SerializeObject(obj);
            return jsonStr;
        }
    }


    public static int ToInt(this object obj, int defaultVal = 0)
    {
        try
        {
            return Convert.ToInt32(obj);
        }
        catch (Exception e)
        {
            Console.Error.WriteLine(e);
            return defaultVal;
        }
    }

    public class ProxyModel
    {
        public string Url;

        public string Method = "get";

        public string Body = "";
    }

    /// <summary>
    /// 采用httpclientfactory请求，socket利用率高
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public static async Task<HttpResponseMessage> ProxyAsync(ProxyModel model)
    {
        var factory = ServiceLocator.GetService<IHttpClientFactory>();
        var client = factory.CreateClient();
        client.Timeout = TimeSpan.FromSeconds(120);

        HttpResponseMessage responseMessage;

        if (new string[] { "POST", "DELETE", "PUT" }.Contains(model.Method?.ToUpper()))
        {
            var bodyStr = model.Body ?? "";

            var ms = new MemoryStream();
            var bodyBytes = Encoding.UTF8.GetBytes(bodyStr);
            ms.Write(bodyBytes, 0, (int)bodyBytes.Length);
            ms.Position = 0;
            HttpContent content = new StreamContent(ms);
            // content.Headers.ContentLength = ms.Length;

            if ((bodyStr.StartsWith("{") && bodyStr.EndsWith("}")) ||
                (bodyStr.StartsWith("[") && bodyStr.EndsWith("]")))
            {
                content.Headers.ContentType =
                    System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
            }
            else
            {
                content.Headers.ContentType =
                    System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
            }

            responseMessage = await client.PostAsync(model.Url, content);
        }
        else
        {
            responseMessage = await client.GetAsync(model.Url);
        }

        return responseMessage;
    }

    /// <summary>
    /// 将图片转成base64
    /// </summary>
    /// <param name="imagePath"></param>
    /// <returns></returns>
    public static string ConvertImageToBase64(string imagePath)
    {
        using (var fs = new FileStream(imagePath, FileMode.Open))
        {
            byte[] imageBytes = new byte[fs.Length];
            fs.Read(imageBytes, 0, (int)fs.Length);

            string base64String = Convert.ToBase64String(imageBytes);

            var ext = Path.GetExtension(imagePath)?.ToLower();
            var preStr = "";
            switch (ext)
            {
                case ".png":
                    preStr = "data:image/png;base64,";
                    break;
                case ".jpg":
                case ".jpeg":
                    preStr = "data:image/jpeg;base64,";
                    break;
                default:
                    preStr = "data:image/jpeg;base64,";
                    break;
            }

            return preStr + base64String;
        }
    }

    public static string ConvertBase64ToImage(string base64String, string imagePath)
    {
        var shortStr = base64String.Substring(0, Math.Min(100, base64String.Length));
        var index = shortStr.IndexOf(";base64,");
        if (index > 0)
        {
            base64String = base64String.Substring(index + ";base64,".Length);
        }

        // Convert base 64 string to byte[]
        byte[] imageBytes = Convert.FromBase64String(base64String);
        // Convert byte[] to Image
        using (var fs = new FileStream(imagePath, FileMode.Create))
        {
            fs.Write(imageBytes, 0, (int)imageBytes.Length);
            return imagePath;
        }
    }

    #region ExecMethodInTime 执行方法，不能超时
    /// <summary>
    /// 执行方法，不能超时
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="curTask"></param>
    /// <param name="timeout">超时时间 毫秒</param>
    /// <returns></returns>
    public static async Task<T> ExecMethodInTime<T>(Task<T> curTask, int timeout = 10000)
    {
        return await ExecMethodInTime(curTask, TimeSpan.FromMilliseconds(timeout));
    }

    /// <summary>
    /// 执行方法，不能超时
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="curTask"></param>
    /// <param name="ts">超时时间</param>
    /// <returns></returns>
    public static async Task<T> ExecMethodInTime<T>(Task<T> curTask, TimeSpan ts)
    {
        if (await Task.WhenAny(curTask, Task.Delay(ts)) == curTask)
        {
            return curTask.Result;
        }
        else
        {
            throw new Exception("请求超时");
        }
    }
    #endregion
}
